#include <QtGui>
#include <iostream>

#include "operationDialog.h"

OperationDialog::OperationDialog(CombinedObject *_combinedObject, ObjectTreeItem *_item, QTreeWidgetItem *_root, Scene *_scene, QWidget *_parent)
    : QDialog(_parent), combinedObject(_combinedObject), item(_item), root(_root), scene(_scene){

    setWindowTitle(QString::fromUtf8("Modificar objeto ").append(QString::number(_combinedObject->getId())));

    const Material &material = combinedObject->getMaterial();
    const double *color = material.getAmbient();
    ambientR = color[0] * 255;
    ambientG = color[1] * 255;
    ambientB = color[2] * 255;

    color = material.getDiffuse();
    diffuseR = color[0] * 255;
    diffuseG = color[1] * 255;
    diffuseB = color[2] * 255;

    color = material.getSpecular();
    specularR = color[0] * 255;
    specularG = color[1] * 255;
    specularB = color[2] * 255;

    operation = combinedObject->getType();
    remove = false;

    createLayout();
}

OperationDialog::~OperationDialog(){
    delete ambientPushButton;
    delete diffusePushButton;
    delete specularPushButton;
    delete operationBox;
}

void OperationDialog::createLayout(){
    QLabel *changeOperationLabel = new QLabel(QString::fromUtf8("Mudar operação:"));

    QComboBox *operationComboBox = new QComboBox();
    operationComboBox->addItem(QString::fromUtf8("União"));
    operationComboBox->addItem(QString::fromUtf8("Interseção"));
    operationComboBox->addItem(QString::fromUtf8("Diferença"));
    operationComboBox->setCurrentIndex(operation);
    connect(operationComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeOperation(int)));


    ambientPushButton = new QPushButton(tr("Cor ambiente"));
    connect(ambientPushButton, SIGNAL(clicked()), this, SLOT(changeAmbient()));

    diffusePushButton = new QPushButton(tr("Cor difusa"));
    connect(diffusePushButton, SIGNAL(clicked()), this, SLOT(changeDiffuse()));

    specularPushButton = new QPushButton(tr("Cor especular"));
    connect(specularPushButton, SIGNAL(clicked()), this, SLOT(changeSpecular()));
    setButtonColor();

    QHBoxLayout *operationLayout = new QHBoxLayout;
    operationLayout->addWidget(changeOperationLabel);
    operationLayout->addWidget(operationComboBox);
    operationLayout->addStretch(1);

    QVBoxLayout *objectLayout = new QVBoxLayout;
    objectLayout->addLayout(operationLayout);
    objectLayout->addWidget(ambientPushButton);
    objectLayout->addWidget(diffusePushButton);
    objectLayout->addWidget(specularPushButton);
    objectLayout->addStretch(1);

    operationBox = new QGroupBox(QString::fromUtf8("Objeto"));
    operationBox->setLayout(objectLayout);


    QCheckBox *removeOperationCheckBox = new QCheckBox(QString::fromUtf8("Cancelar operação"));
    connect(removeOperationCheckBox, SIGNAL(clicked(bool)), this, SLOT(removeOperation(bool)));



    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
    connect(buttonBox, SIGNAL(accepted()), this, SLOT(change()));
    connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
    buttonBox->setLocale(QLocale(QLocale::Portuguese, QLocale::Brazil));

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(operationBox);
    mainLayout->addWidget(removeOperationCheckBox);
    mainLayout->addWidget(buttonBox);
    mainLayout->addStretch(1);

    setLayout(mainLayout);
}

void OperationDialog::setButtonColor(){
    QString ambientStr;
    if(ambientR + ambientB + ambientG < 400){
        ambientStr = QString::fromUtf8("color: rgb(255, 255, 255);\n");
    }else{
        ambientStr = QString::fromUtf8("color: rgb(0, 0, 0);\n");
    }
    ambientStr.append(QString::fromUtf8("background-color: rgb("));
    ambientStr.append(QString::number(ambientR));
    ambientStr.append(QString::fromUtf8(", "));
    ambientStr.append(QString::number(ambientG));
    ambientStr.append(QString::fromUtf8(", "));
    ambientStr.append(QString::number(ambientB));
    ambientStr.append(QString::fromUtf8(");"));

    ambientPushButton->setStyleSheet(ambientStr);



    QString diffuseStr;
    if(diffuseR + diffuseB + diffuseG < 400){
        diffuseStr = QString::fromUtf8("color: rgb(255, 255, 255);\n");
    }else{
        diffuseStr = QString::fromUtf8("color: rgb(0, 0, 0);\n");
    }
    diffuseStr.append(QString::fromUtf8("background-color: rgb("));
    diffuseStr.append(QString::number(diffuseR));
    diffuseStr.append(QString::fromUtf8(", "));
    diffuseStr.append(QString::number(diffuseG));
    diffuseStr.append(QString::fromUtf8(", "));
    diffuseStr.append(QString::number(diffuseB));
    diffuseStr.append(QString::fromUtf8(");"));

    diffusePushButton->setStyleSheet(diffuseStr);



    QString specularStr;
    if(specularR + specularB + specularG < 400){
        specularStr = QString::fromUtf8("color: rgb(255, 255, 255);\n");
    }else{
        specularStr = QString::fromUtf8("color: rgb(0, 0, 0);\n");
    }
    specularStr.append(QString::fromUtf8("background-color: rgb("));
    specularStr.append(QString::number(specularR));
    specularStr.append(QString::fromUtf8(", "));
    specularStr.append(QString::number(specularG));
    specularStr.append(QString::fromUtf8(", "));
    specularStr.append(QString::number(specularB));
    specularStr.append(QString::fromUtf8(");"));

    specularPushButton->setStyleSheet(specularStr);
}

void OperationDialog::change(){
    std::vector<Object *> objects;
    if(remove){
        QTreeWidgetItem *parent = item->parent();
        if(parent == NULL){
            parent = root;
            scene->deleteObject(combinedObject);
        }else{
            ((CombinedObject *)((ObjectTreeItem *)parent)->getObject())->deleteObject(combinedObject);
        }

        for(int i = item->childCount(); i > 0; i--){
            QTreeWidgetItem *currentItem = item->child( i-1 );
            Object *currentObject = ((ObjectTreeItem *)currentItem)->getObject();
            if(parent == root){
                scene->addObject(currentObject);
                objects.push_back(currentObject);
            }else{
                ((CombinedObject *)((ObjectTreeItem *)parent)->getObject())->addObject(currentObject);
            }
            combinedObject->deleteObject(currentObject);

            item->removeChild(currentItem);
            parent->addChild(currentItem);
        }


        parent->removeChild(item);
        delete item;
        delete combinedObject;

        if(parent != root){
            objects.clear();
            while(parent->parent() != NULL){
                parent = parent->parent();
            }
            objects.push_back(((ObjectTreeItem *)parent)->getObject());
        }


    }else{
        combinedObject->changeOperation(operation);
        combinedObject->setMaterial(Material(ambientR/255.0, ambientG/255.0, ambientB/255.0, diffuseR/255.0, diffuseG/255.0, diffuseB/255.0, specularR/255.0, specularG/255.0, specularB/255.0));
        item->update();
        objects.push_back(combinedObject);
    }

    accept();
    done();
}

void OperationDialog::changeAmbient(){
    QColor color = QColorDialog::getColor(QColor(ambientR, ambientG, ambientB), this, "Escolha a cor ambiente");
    if (color.isValid()){
        ambientR = color.red();
        ambientG = color.green();
        ambientB = color.blue();
    }
    setButtonColor();
}

void OperationDialog::changeDiffuse(){
    QColor color = QColorDialog::getColor(QColor(diffuseR, diffuseG, diffuseB), this, "Escolha a cor difusa");
    if (color.isValid()){
        diffuseR = color.red();
        diffuseG = color.green();
        diffuseB = color.blue();
    }
    setButtonColor();
}

void OperationDialog::changeSpecular(){
    QColor color = QColorDialog::getColor(QColor(specularR, specularG, specularB), this, "Escolha a cor especular");
    if (color.isValid()){
        specularR = color.red();
        specularG = color.green();
        specularB = color.blue();
    }
    setButtonColor();
}

void OperationDialog::changeOperation(int _index){
    operation = _index;
}

void OperationDialog::removeOperation(bool _b){
    operationBox->setDisabled(_b);
    remove = _b;
}
